package com.filetransfer.command;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;


import com.filetransfer.client.state.ServerReceiveControl;
import com.filetransfer.client.message.SendMessageAdapter;
import com.filetransfer.config.FileServerConfig;
import com.filetransfer.plugin.ServerFilePlugin;
import com.filetransfer.server.fileserver.FileReceiveCallBack;
import com.filetransfer.util.ExceptionUtil;
import com.filetransfer.util.StringUtil;



/**
 * 功能说明: 解析FileServer配置文件 <br>
 * 开发人员: hanxuetong<br>
 * 开发时间: 2014-10-8 <br>
 * 
 */
public class FileServerParser {

	private FileServerConfig fileServerConfig;
	private ServerReceiveControl serverReceiveControl;
	
	private String serverXmlPath="fileserver.xml";
	
	/**
	 * 从节点实例化出一个对象
	 * @param element
	 * @param cls
	 * @return
	 * @throws ClassNotFoundException 
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws IllegalArgumentException 
	 */
	@SuppressWarnings("unchecked")
	public <T> T getNewInstanceFromElement(Element element,Object ...param) throws Exception
	{
		//String beanName=element.attributeValue("beanName");
		String classPath=element.attributeValue("class");
		T obj=null;
		/*if(StringUtil.isNotEmpty(beanName))
		{
			obj=(T) ApplicationContextProvider.getBean(beanName);
		}else */if(StringUtil.isNotEmpty(classPath)){
			
		
				try {
					@SuppressWarnings("rawtypes")
					Class clses = Class.forName(classPath);
					
					if(param!=null&&param.length>0)  //多参数时
					{
						@SuppressWarnings("rawtypes")
						Constructor[] cons = clses.getDeclaredConstructors();
						for(int i=0;i<cons.length;i++){
							if(param.length==cons[i].getParameterTypes().length)
							{
								obj=(T)cons[i].newInstance(param);
								return obj;
							}
							
						}
					}else{
						obj=(T)clses.newInstance();
						return obj;
					}
				} catch (Exception e) {
					e.printStackTrace();
					throw new RuntimeException("文件中转服务器配置fileserver.xml有问题");
				}
				
				//Constructor constructor = clses.getConstructor(param[i++],param[i++]);
				
				//obj=(T)constructor.newInstance(initargs);
				//obj=(T) Class.forName(classPath).newInstance();
		
			
		}
		return obj;
	}

	
	public <T> T getNewObjectFromElement(Element element) throws Exception
	{
		List<Element> paramEles=element.elements("param");
		T obj=null;
		if(paramEles!=null&&paramEles.size()>0)  //有参数
		{
			Object[] params=new Object[paramEles.size()];
			for(int i=0;i<paramEles.size();i++)
			{
				params[i]=getParamObjByString(paramEles.get(i).getTextTrim());
			}
			obj=getNewInstanceFromElement(element,params);
			
		}else{ //无参
			obj=getNewInstanceFromElement(element);
			
		}
		return obj;
	}
	
	public <T> T getNewObject(Element fileserverEle,String elementKey) throws Exception
	{
		Element objele=fileserverEle.element(elementKey);
		if(objele!=null)
		{
			T obj=getNewObjectFromElement(objele);
			return obj;
		}
		return null;
	}
	
	
	/**
	 * 获取参数实例
	 * @param param
	 * @return
	 */
	private Object getParamObjByString(String param)
	{
		if("fileServerConfig".equals(param))
		{
			return fileServerConfig;
		}
		if("serverReceiveControl".equals(param))
		{
			return serverReceiveControl;
		}
		return param;
	}
	
	/**
	 * 解析出ServerConfig属性
	 * @param fileserverEle
	 */
	public void parserServerConfig(Element fileserverEle)
	{
		String isTransitServer=fileserverEle.attributeValue("isTransitServer");
		String port=fileserverEle.attributeValue("port");
		String filePath=fileserverEle.attributeValue("filePath");
		String soTimeout=fileserverEle.attributeValue("soTimeout");
		String poolSize=fileserverEle.attributeValue("poolSize");
		String isAuthorityCheck=fileserverEle.attributeValue("isAuthorityCheck");
		String authorityKey=fileserverEle.attributeValue("authorityKey");
		
		if(StringUtil.isAllNotEmpty(port,filePath))
		{
			if(isTransitServer!=null&&!Boolean.parseBoolean(isTransitServer))  //是否不是中转服务器
			{
				fileServerConfig=new FileServerConfig(filePath, Integer.parseInt(port),false);
			}else{
				fileServerConfig=new FileServerConfig(filePath, Integer.parseInt(port), true);
			}
			
			if(StringUtil.isNotEmpty(soTimeout))
			{
				fileServerConfig.setSoTimeout(Integer.parseInt(soTimeout));
			}
			if(StringUtil.isNotEmpty(poolSize))
			{
				fileServerConfig.setPoolSize(Integer.parseInt(poolSize));
			}
			if(StringUtil.isNotEmpty(isAuthorityCheck))
			{
				fileServerConfig.setAuthorityCheck(Boolean.parseBoolean(isAuthorityCheck));
			}
			if(StringUtil.isNotEmpty(authorityKey))
			{
				fileServerConfig.setAuthorityKey(authorityKey);
			}
			
		}else{
			ExceptionUtil.throwException("配置中 filePath port 不能为空");
		}
		serverReceiveControl=new ServerReceiveControl(fileServerConfig);
	}
	
	public void parser() throws Exception
	{
		
		SAXReader reader = new SAXReader();  
		String path="";
		try {
			URL url=FileServerParser.class.getResource("/");
			path=url.getPath()+serverXmlPath;
		} catch (Exception e) {
			
			path=serverXmlPath;
			
		}
		System.out.println("serverXml路径："+path);
		Document document = reader.read(path);
		Element root = document.getRootElement();
		Element fileserverEle=root.element("fileserver");
	
		 parserServerConfig(fileserverEle);
	
		
		
		FileReceiveCallBack fileReceiveCallBack=getNewObject(fileserverEle,"fileReceiveCallBack");
		if(fileReceiveCallBack!=null)
		{
			serverReceiveControl.setFileReceiveCallBack(fileReceiveCallBack);
		}
			
		
		SendMessageAdapter sendMessageAdapter=getNewObject(fileserverEle,"sendMessageAdapte");
		if(sendMessageAdapter!=null)
		{
			serverReceiveControl.setSendMessageAdapter(sendMessageAdapter);
		}
		

		Element plugins=fileserverEle.element("plugins");
		if(plugins!=null)
		{
			List<Element> pluginList=plugins.elements("plugin");
			if(pluginList!=null&&pluginList.size()>0)
			{
				for(Element pluginEle:pluginList)
				{
					ServerFilePlugin serverFilePlugin =getNewObjectFromElement(pluginEle);
					if(serverFilePlugin!=null)
					{
						serverReceiveControl.addServerFilePlugin(serverFilePlugin);
					}
				}
				
			}
		}
		
	}
	
	
	public ServerReceiveControl getServerReceiveControl() {
		return serverReceiveControl;
	}





	public static void main(String[] args) throws DocumentException, InstantiationException, IllegalAccessException, ClassNotFoundException {
		
		//FileServerParser fileServerParser=new FileServerParser();
		//fileServerParser.parser();
	}
	
}
